﻿using System;

namespace BankSimulation
{
    // 定义枚举，表示交易结果
    public enum TransactionResult
    {
        Success,
        InsufficientFunds,
        BadCash
    }

    // 定义事件参数类
    public class BigMoneyArgs : EventArgs
    {
        public Account Account { get; set; }
        public decimal Amount { get; set; }

        public BigMoneyArgs(Account account, decimal amount)
        {
            Account = account;
            Amount = amount;
        }
    }

    // 自定义异常类：表示破损的钞票
    public class BadCashException : Exception
    {
        public BadCashException(string message) : base(message) { }
    }

    // 账户基类
    public class Account
    {
        public string AccountNumber { get; private set; }
        public decimal Balance { get; protected set; }

        public Account(string accountNumber, decimal initialBalance)
        {
            AccountNumber = accountNumber;
            Balance = initialBalance;
        }

        // 存款方法
        public virtual void Deposit(decimal amount)
        {
            if (amount <= 0)
                throw new ArgumentException("存款金额必须大于零。");
            Balance += amount;
        }

        // 取款方法
        public virtual TransactionResult Withdraw(decimal amount)
        {
            if (amount <= 0)
                throw new ArgumentException("取款金额必须大于零。");

            if (Balance >= amount)
            {
                Balance -= amount;
                return TransactionResult.Success;
            }
            else
            {
                return TransactionResult.InsufficientFunds;
            }
        }
    }

    // 信用账户类，继承自账户类
    public class CreditAccount : Account
    {
        public decimal CreditLimit { get; private set; }

        public CreditAccount(string accountNumber, decimal initialBalance, decimal creditLimit)
            : base(accountNumber, initialBalance)
        {
            CreditLimit = creditLimit;
        }

        // 重写取款方法，允许透支
        public override TransactionResult Withdraw(decimal amount)
        {
            if (amount <= 0)
                throw new ArgumentException("取款金额必须大于零。");

            if (Balance + CreditLimit >= amount)
            {
                Balance -= amount;
                return TransactionResult.Success;
            }
            else
            {
                return TransactionResult.InsufficientFunds;
            }
        }
    }

    // ATM类
    public class ATM
    {
        public event EventHandler<BigMoneyArgs> BigMoneyFetched; // 事件声明

        private Random _random = new Random();

        public void Withdraw(Account account, decimal amount)
        {
            try
            {
                // 模拟坏钞异常
                if (_random.NextDouble() < 0.3) // 30% 概率发生坏钞
                {
                    throw new BadCashException("发生坏钞，请重新尝试取款。");
                }

                // 执行取款
                var result = account.Withdraw(amount);

                // 触发大额取款事件
                if (result == TransactionResult.Success && amount > 10000)
                {
                    OnBigMoneyFetched(account, amount);
                }

                Console.WriteLine($"取款成功，余额：{account.Balance}");
            }
            catch (BadCashException ex)
            {
                Console.WriteLine($"错误：{ex.Message}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发生错误：{ex.Message}");
            }
        }

        // 事件触发器
        protected virtual void OnBigMoneyFetched(Account account, decimal amount)
        {
            BigMoneyFetched?.Invoke(this, new BigMoneyArgs(account, amount));
        }
    }

    // 主程序
    class Program
    {
        static void Main(string[] args)
        {
            // 创建账户和信用账户
            Account account = new Account("12345", 5000);
            CreditAccount creditAccount = new CreditAccount("67890", 3000, 2000);

            // 创建ATM对象并注册事件
            ATM atm = new ATM();
            atm.BigMoneyFetched += (sender, e) =>
            {
                Console.WriteLine($"警告：账户 {e.Account.AccountNumber} 取走大笔金额 {e.Amount} 元！");
            };

            // 模拟ATM取款操作
            atm.Withdraw(account, 6000);  // 取款小于10000
            atm.Withdraw(creditAccount, 15000); // 取款大于10000
            atm.Withdraw(account, 10000); // 取款等于10000
            atm.Withdraw(account, 7000); // 取款超过余额

            Console.ReadLine();
        }
    }
}
